#include "statsxx/preprocess/Preprocessor.hpp"

// STL
#include <algorithm>  // std::minmax_element()
#include <vector>     // std::vector<>

// jScience
#include "jScience/linalg/Matrix.hpp" // Matrix<>
#include "jstats.hpp" // mean()


//
// DESC: Standardizes data to have zero mean and unit standard deviation.
//
inline Vector<double> Preprocessor::standardize_data(
                                                     Vector<double> x
                                                     ) const
{
    if(this->init)
    {

        for(auto i = 0; i < x.size(); ++i)
        {
            // NOTE: It is better to compare x_max to x_min that x_s; the former is a direct comparison, while the latter may have numerical issues.

            if( this->x_max[i] != this->x_min[i] )
            {
                x(i) = (x(i) - this->x_mean[i])/this->x_s[i];
            }
            else
            {
                x(i) = 0.;
            }

        }

    }

    return x;
}

inline Matrix<double> Preprocessor::standardize_data(
                                                     Matrix<double> X
                                                     ) const
{
    if(this->init)
    {

        for( int i = 0; i < X.get_size(0); ++i )
        {
            for( int j = 0; j < X.get_size(1); ++j )
            {
                // NOTE: See the comments in Preprocessor::standardize_data().

                if( this->x_max[j] != this->x_min[j] )
                {
                    X(i,j) = (X(i,j) - this->x_mean[j])/this->x_s[j];
                }
                else
                {
                    X(i,j) = 0.;
                }
            }
        }

    }

    return X;
}
